#!/bin/sh
###################################################
# Usage: 10-init-web-server-config.sh
###################################################
# This script prepares the usage of PHP-FPM-NGINX and PHP-FPM-Apache with S6 overlay. The script
# will execute at container initialization and will process templates from environment variables
# and enable the necessary websites.
script_name="init-webserver-config"

# Check if S6 is initialized
if [ "$S6_INITIALIZED" != "true" ]; then
    if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then
        echo "👉 $script_name: S6 is not initialized, so web server configuration will NOT be performed."
    fi
    exit 0
fi

##########
# Functions
##########
detect_web_server_type() {
    if command -v apache2 >/dev/null 2>&1; then
      echo "Apache"
    elif command -v nginx >/dev/null 2>&1; then
      echo "NGINX"
    else
      echo "Unknown"
    fi
}

process_template() {
    template_file=$1
    output_file=$2

    if [ -f "$output_file" ]; then
        echo "ℹ️ NOTICE ($script_name): $output_file already exists, so we'll use the existing file."
        return 0
    fi

    if [ ! -f "$template_file" ]; then
        echo "🛑 ERROR ($script_name): Unable to initialize container. $output_file doesn't exist and we're unable to find a template for $template_file."
        return 1
    fi

    # Get all environment variables starting with 'NGINX_', 'SSL_', `LOG_`, 'APACHE_', and 'HEALTHCHECK_PATH'
    subst_vars=$(env | grep -E '^(PHP_|NGINX_|SSL_|LOG_|APACHE_|HEALTHCHECK_PATH)' | cut -d= -f1 | awk '{printf "${%s},",$1}' | sed 's/,$//')

    # Validate that all required variables are set
    for var_name in $(echo "$subst_vars" | tr ',' ' '); do
        eval "value=\$$var_name" # Use eval to get the value of var_name
        if [ -z "$value" ]; then
            echo "🛑 ERROR ($script_name): Environment variable $var_name is not set."
            return 1
        fi
    done

    echo "($script_name): Processing $template_file → $output_file..."
    envsubst "$subst_vars" < "$template_file" > "$output_file"

    if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then
        echo "$script_name: Contents of $output_file:"
        cat $output_file
        echo
    fi
}

enable_apache_conf() {
    APACHE_CONF_AVAILABLE_DIR="/etc/apache2/conf-available"
    APACHE_CONF_ENABLED_DIR="/etc/apache2/conf-enabled"

    # Check if at least one configuration name was provided
    if [ $# -eq 0 ]; then
        echo "Usage: enable_apache_conf <conf-name>..."
        return 1
    fi

    for conf_name in "$@"; do
        SOURCE_FILE="${APACHE_CONF_AVAILABLE_DIR}/${conf_name}.conf"
        TARGET_FILE="${APACHE_CONF_ENABLED_DIR}/${conf_name}.conf"

        if [ ! -f "$SOURCE_FILE" ]; then
            echo "🛑 ERROR ($script_name): Configuration file '$SOURCE_FILE' does not exist"
            return 1
        fi

        # Create a symbolic link if it already doesn't exist
        if [ ! -e "$TARGET_FILE" ]; then
          ln -s "$SOURCE_FILE" "$TARGET_FILE" && echo "ℹ️ NOTICE ($script_name): Enabled configuration '${conf_name}'..."
        else
          echo "ℹ️ NOTICE ($script_name): '${conf_name}' configuration already enabled, skipping..."
        fi
    done
}

enable_apache_site (){
    ssl_mode=$1
    apache2_enabled_site_path="/etc/apache2/sites-enabled"

    # Transform to lowercase
    ssl_mode=$(echo "$ssl_mode" | tr '[:upper:]' '[:lower:]')

    # Enable the site
    if [ ! -e "$apache2_enabled_site_path/ssl-$ssl_mode.conf" ]; then
        echo "ℹ️ NOTICE ($script_name): Enabling Apache site with SSL '$ssl_mode'..."
        ln -s "/etc/apache2/sites-available/ssl-$ssl_mode.conf" "$apache2_enabled_site_path/ssl-$ssl_mode.conf"
    else
          echo "ℹ️ NOTICE ($script_name): Apache site with the SSL '$ssl_mode' already enabled, Skipping..."
    fi
}

enable_nginx_site (){
    ssl_mode=$1
    default_nginx_site_config="/etc/nginx/conf.d/default.conf"

    # Transform to lowercase
    ssl_mode=$(echo "$ssl_mode" | tr '[:upper:]' '[:lower:]')

    # Link the site available to be the active site
    if [ -f "$default_nginx_site_config" ]; then
        echo "ℹ️ NOTICE ($script_name): $default_nginx_site_config already exists, so we'll use the provided configuration."
    else
        echo "ℹ️ NOTICE ($script_name): Enabling NGINX site with SSL \"$ssl_mode\"..."
        # Create the base directory if it doesn't exist
        base_dir=$(dirname "$default_nginx_site_config")
        mkdir -p "$base_dir"
        ln -s "/etc/nginx/sites-available/ssl-$ssl_mode" "$default_nginx_site_config"
    fi
}

##########
# Main
##########
SERVER_TYPE=$(detect_web_server_type)

if [ "$DISABLE_DEFAULT_CONFIG" = false ]; then
    if [ "$SERVER_TYPE" = "Apache" ]; then
        enable_apache_conf remoteip security serversideup
        enable_apache_site "$SSL_MODE"
    elif [ "$SERVER_TYPE" = "NGINX" ]; then
        process_template /etc/nginx/nginx.conf.template /etc/nginx/nginx.conf
        process_template /etc/nginx/site-opts.d/http.conf.template /etc/nginx/site-opts.d/http.conf
        process_template /etc/nginx/site-opts.d/https.conf.template /etc/nginx/site-opts.d/https.conf
        process_template /etc/nginx/sites-available/ssl-full.template /etc/nginx/sites-available/ssl-full

        # Configure NGINX IP listening protocol if NGINX is installed
        nginx_config_files="/etc/nginx/site-opts.d/http.conf /etc/nginx/site-opts.d/https.conf /etc/nginx/sites-available/ssl-full"
        case "$NGINX_LISTEN_IP_PROTOCOL" in
            all)
                # Do nothing, keep both IPv4 and IPv6
                ;;
            ipv4)
                echo "ℹ️ NOTICE (init-webserver-config): Setting IPv4 only for NGINX configuration..."
                for config_file in $nginx_config_files; do
                    if [ -f "$config_file" ]; then
                        sed -i '/listen \[::\]:/d' "$config_file"
                    fi
                done
                ;;
            ipv6)
                echo "ℹ️ NOTICE (init-webserver-config): Setting IPv6 only for NGINX configuration..."
                for config_file in $nginx_config_files; do
                    if [ -f "$config_file" ]; then
                        sed -i '/^[[:space:]]*listen [0-9]/d' "$config_file"
                    fi
                done
                ;;
            *)
                echo "🛑 ERROR ($script_name): Invalid NGINX_LISTEN_IP_PROTOCOL value: $NGINX_LISTEN_IP_PROTOCOL"
                return 1
                ;;
        esac

        enable_nginx_site "$SSL_MODE"
    else
        echo "🛑 ERROR ($script_name): Neither Apache nor NGINX could be detected."
        return 1
    fi
else
    if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then
        echo "👉 $script_name: DISABLE_DEFAULT_CONFIG does not equal \"false\", so web server initialization will NOT be performed."
    fi
fi